Creating website templates using AI
I used Google Gemini, GitHub Copilot, and locally running large language models (LLMs) to help create templates for my static site.
When converting my site to a static site generator (SSG), I learned they require templates to convert my Markdown files to HTML based on the associated template. Templates also enforce structure and allow dynamic content.
I didn’t know a thing about templating languages, so I turned to large language models (LLMs) to help me write code for the templates on my site. There are many templating languages, but I chose Nunjucks basically because it was the default for a lot of the Eleventy documentation. Nunjucks is based on Jinja.
What I learned about LLMs
LLMs can only do so much, and are often just plain wrong (known as hallucinations). What I learned is that if you want good answers, then you have to think through your logic. It’s your typical GIGO (garbage in, garbage out) cycle, so it’s helpful to write it down regardless of the language.
Over the course of my back-and-forth with the LLMs, understanding the logic I wanted helped me to accurately frame the question to the LLM. This made me think more and more about how to craft prompts, and how technical writers can educate regular folks how best to use AI.
On the plus side, the LLMs did things it would’ve taken me a lot more time to learn and do manually. Here are a few things that the LLMs helped me work through:
-
Continual content/metadata revision.
-
Repeatedly interating on templates.
-
Trying to modularize by abstracting templates in templates.
-
Sorting entries like podcast episodes in reverse order by appending
| reverse -
How to split arrays of items and display them using slices.
-
How to create a “shortcode” to programmatically display the current year:
eleventyConfig.addShortcode("year", () => `${new Date().getFullYear()}`); -
Collections (essentially tags) and how to use them to group topics.
Gemini vs. Copilot
I pitted Google’s Gemini against GitHub Copilot. I prompted Gemini with:
I'm creating a web site using Eleventy, Nunjucks, Tailwind CSS, HTML, and Markdown. I'd like your help with a template for the homepage.
Here’s the response. Note the items in braces are part of the Nunjucks template language.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Eleventy Site</title>
<link href="/styles/tailwind.css" rel="stylesheet">
</head>
<body class="bg-gray-100 text-gray-900 font-sans">
<header class="bg-blue-600 text-white p-4 shadow-md">
<h1 class="text-3xl font-bold">Welcome to My Site</h1>
</header>
<main class="container mx-auto mt-8 px-4">
<section class="mb-8">
<h2 class="text-2xl font-semibold">About</h2>
<p class="mt-2">
{% markdown %}
Welcome to my website. Here you will find information about me and my projects.
{% endmarkdown %}
</p>
</section>
<section class="mb-8">
<h2 class="text-2xl font-semibold">Latest Content</h2>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{% assign allItems = collections.all | sort_by: 'date', 'desc' %}
{% for item in allItems | slice(0, 6) %}
<div class="bg-white p-4 shadow-md">
<h3 class="text-xl font-semibold">{{ item.data.title }}</h3>
<p>{{ item.data.description }}</p>
</div>
{% endfor %}
</div>
</section>
</main>
<footer class="bg-gray-800 text-white p-4 mt-8">
<p>© 2025 My Eleventy Site</p>
</footer>
</body>
</html>
Copilot said that the Gemini version was well-structured and accurate. Here’s the result:

The 2026 update
I’m writing most of this post a year after I drafted it. I fed the same prompt into the qwen3-coder-30b-a3b-instruct model that I’m running locally in LM Studio, and it output the following. It’s pretty obvious how advanced even locally running LLMs with a relatively small number of parameters have become in the past year. The 2026 version is far more detailed — and documented!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
<meta name="description" content="{{ description }}">
<link href="/styles.css" rel="stylesheet">
</head>
<body class="bg-gray-50 text-gray-900">
<header class="bg-white shadow">
<div class="container mx-auto px-4 py-6 flex justify-between items-center">
<h1 class="text-2xl font-bold">{{ title }}</h1>
<nav>
<ul class="flex space-x-4">
<li><a href="/" class="hover:text-blue-600">Home</a></li>
<li><a href="/about" class="hover:text-blue-600">About</a></li>
<li><a href="/posts" class="hover:text-blue-600">Posts</a></li>
</ul>
</nav>
</div>
</header>
<main class="container mx-auto px-4 py-8">
<!-- Hero Section -->
<section class="text-center mb-12">
<h2 class="text-4xl font-bold mb-4">{{ title }}</h2>
<p class="text-xl text-gray-600 max-w-2xl mx-auto">{{ description }}</p>
</section>
<!-- Featured Content -->
<section class="mb-12">
<h3 class="text-2xl font-semibold mb-6">Latest Posts</h3>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{% for post in collections.posts | reverse %}
<article class="bg-white rounded-lg shadow-md overflow-hidden">
<a href="{{ post.url }}">
<h4 class="text-xl font-semibold p-4 hover:text-blue-600">{{ post.data.title }}</h4>
</a>
<div class="p-4 text-gray-600">
{{ post.templateContent | slice(0, 150) }}...
</div>
</article>
{% endfor %}
</div>
</section>
<!-- About Section -->
<section class="bg-white rounded-lg shadow-md p-6 mb-8">
<h3 class="text-2xl font-semibold mb-4">About This Site</h3>
<p>This is a simple homepage built with Eleventy, Nunjucks, Tailwind CSS, HTML and Markdown.</p>
</section>
<!-- Newsletter Signup -->
<section class="bg-blue-50 rounded-lg p-6">
<h3 class="text-xl font-semibold mb-2">Stay Updated</h3>
<p class="mb-4">Subscribe to get the latest posts delivered to your inbox.</p>
<form class="flex flex-col sm:flex-row gap-2">
<input type="email" placeholder="Your email address" class="flex-grow px-4 py-2 rounded border focus:outline-none focus:ring-2 focus:ring-blue-500">
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">Subscribe</button>
</form>
</section>
</main>
<footer class="bg-gray-800 text-white py-8">
<div class="container mx-auto px-4 text-center">
<p>© {{ "now" | date("YYYY") }} {{ title }}. All rights reserved.</p>
</div>
</footer>
</body>
</html>